JavaScriptでブラウザのインターネット接続を判定する方法
Reactで構築しているWEBサイトにおいて、事前にインターネットの接続状態を判別させるケースがあり、JavaScriptでどのような実現方法があるのか調べました。先に結論を言いますと、Fetch APIやXHRを使用して公開ファイルへのアクセスを検証する方法が確実です。
NavigatorOnLine
window.navigator.onLine
はブラウザのネットワーク接続状態を真偽値で返します。
if (window.navigator.onLine) { console.log("online"); } else { console.log("offline"); }
このAPIはブラウザによって挙動に違いがあります。また、次の説明文からインターネットの接続状態を判別するのには適さない事が分かりました。
Chrome および Safari は、ブラウザがローカルエリアネットワーク (LAN) またはルータに接続できないときにオフライン、それ以外の状況では true を返します。従って、false 値が返る場合はブラウザがオフラインであると考えることができますが、true 値は必ずインターネットにアクセスできると考えることはできません。仮想イーサネットアダプタを持つ仮想化ソフトウェアを実行しているコンピュータでは常に "接続中" になるなど、偽陽性になる可能性があります。
Firefox および Internet Explorer は、ブラウザをオフラインモードに切り替えると false 値を送信します。Firefox 41 まで、他の状態では true 値を返していました。Firefox 41 より OS X および Windows で、実際のネットワーク接続状態に従って値を返します。
引用元: window.navigator.onLine - Web API | MDN
Network Information API
window.navigator.connection
はネットワークの接続情報を返します。
console.log(window.navigator.connection.type);
次のいずれかの値がコンソールに出力されます。
値 | 説明 |
---|---|
bluetooth | Bluetooth接続 |
cellular | セルラー接続(EDGE、HSPA、LTEなど) |
ethernet | イーサネット接続 |
none | ネットワーク接続なし |
mixed | 複数の接続タイプを使用 |
other | その他の接続タイプ |
unknown | 接続タイプの特定が不可 |
wifi | Wi-Fi接続 |
wimax | WiMAX接続 |
このAPIは接続タイプにより、ストリーミングサービスの帯域幅を調整するなど、幅広い用途に使えそうですが、現状ではIEやSafariに対応していません。
XMLHttpRequest
XMLHttpRequest(XHR)はHTTPリクエストを発行して、レスポンスを受け取ります。xhr.onerror
でネットワーク接続エラーを判別する事ができます。
const xhr = new XMLHttpRequest(); xhr.open("GET", "/favicon.ico"); xhr.send(); xhr.onload = () => { console.log(xhr.response); }; xhr.onerror = () => { console.log("Network Error"); };
Fetch API
Fetch APIはXMLHttpRequestよりもシンプルにHTTPリクエストを発行できます。
fetch("/favicon.ico") .then(response => { console.log(response); }) .catch(error => { console.log("Network Error"); });
次のような関数でインターネットへの接続を判定するようにしました。
const checkOnline = async () => { const date = new Date(); const timestamp = date.getTime(); try { await fetch(`/favicon.ico?${timestamp}`); } catch { return false; } return true; };
Fetch APIはIEが未対応なので、Polyfillを使うのが良いと思います。
github/fetch: A window.fetch JavaScript polyfill.
まとめ
ローカルエリアネットワーク(LAN)の接続確認はwindow.navigator.onLine
、インターネットの接続確認にはFetch APIを使用するのが良いと思います。Fetch APIやXHRを使用する際には、キャッシュにも注意してみてください。